package com.example.menhoo.toollibrary.common.utils;

import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Build;
import android.provider.MediaStore;

import com.example.menhoo.toollibrary.android.log.Log;
import com.example.menhoo.toollibrary.common.assist.Base64;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;

public class BitmapUtil {

    private static final String TAG = BitmapUtil.class.getSimpleName();

    /**
     * convert Bitmap to byte array
     */
    public static byte[] bitmapToByte(Bitmap b) {
        ByteArrayOutputStream o = new ByteArrayOutputStream();
        b.compress(Bitmap.CompressFormat.PNG, 100, o);
        return o.toByteArray();
    }

    /**
     * convert byte array to Bitmap
     */
    public static Bitmap byteToBitmap(byte[] b) {
        return (b == null || b.length == 0) ? null : BitmapFactory.decodeByteArray(b, 0, b.length);
    }

    /**
     * 把bitmap转换成Base64编码String
     */
    public static String bitmapToString(Bitmap bitmap) {
        return Base64.encodeToString(bitmapToByte(bitmap), Base64.DEFAULT);
    }

    /**
     * convert Drawable to Bitmap
     */
    public static Bitmap drawableToBitmap(Drawable drawable) {
        return drawable == null ? null : ((BitmapDrawable) drawable).getBitmap();
    }

    /**
     * convert Bitmap to Drawable
     */
    public static Drawable bitmapToDrawable(Bitmap bitmap) {
        return bitmap == null ? null : new BitmapDrawable(bitmap);
    }

    /**
     * scale image
     */
    public static Bitmap scaleImageTo(Bitmap org, int newWidth, int newHeight) {
        return scaleImage(org, (float) newWidth / org.getWidth(), (float) newHeight / org.getHeight());
    }

    /**
     * scale image
     */
    public static Bitmap scaleImage(Bitmap org, float scaleWidth, float scaleHeight) {
        if (org == null) {
            return null;
        }
        Matrix matrix = new Matrix();
        matrix.postScale(scaleWidth, scaleHeight);
        return Bitmap.createBitmap(org, 0, 0, org.getWidth(), org.getHeight(), matrix, true);
    }



    public static Bitmap createBitmapThumbnail(Bitmap bitMap, boolean needRecycle, int newHeight, int newWidth) {
        int width = bitMap.getWidth();
        int height = bitMap.getHeight();
        // 计算缩放比例
        float scaleWidth = ((float) newWidth) / width;
        float scaleHeight = ((float) newHeight) / height;
        // 取得想要缩放的matrix参数
        Matrix matrix = new Matrix();
        matrix.postScale(scaleWidth, scaleHeight);
        // 得到新的图片
        Bitmap newBitMap = Bitmap.createBitmap(bitMap, 0, 0, width, height, matrix, true);
        if (needRecycle)
            bitMap.recycle();
        return newBitMap;
    }

    public static boolean saveBitmap(Bitmap bitmap, File file) {
        if (bitmap == null)
            return false;
        FileOutputStream fos = null;
        try {
            fos = new FileOutputStream(file);
            bitmap.compress(Bitmap.CompressFormat.PNG, 100, fos);
            fos.flush();
            return true;
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (fos != null) {
                try {
                    fos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return false;
    }

    public static boolean saveBitmap(Bitmap bitmap, String absPath) {
        return saveBitmap(bitmap, new File(absPath));
    }

    public static Intent buildImageGetIntent(Uri saveTo, int outputX, int outputY, boolean returnData) {
        return buildImageGetIntent(saveTo, 1, 1, outputX, outputY, returnData);
    }

    public static Intent buildImageGetIntent(Uri saveTo, int aspectX, int aspectY,
                                             int outputX, int outputY, boolean returnData) {
        Log.i(TAG, "Build.VERSION.SDK_INT : " + Build.VERSION.SDK_INT);
        Intent intent = new Intent();
        if (Build.VERSION.SDK_INT < 19) {
            intent.setAction(Intent.ACTION_GET_CONTENT);
        } else {
            intent.setAction(Intent.ACTION_OPEN_DOCUMENT);
            intent.addCategory(Intent.CATEGORY_OPENABLE);
        }
        intent.setType("image/*");
        intent.putExtra("output", saveTo);
        intent.putExtra("aspectX", aspectX);
        intent.putExtra("aspectY", aspectY);
        intent.putExtra("outputX", outputX);
        intent.putExtra("outputY", outputY);
        intent.putExtra("scale", true);
        intent.putExtra("return-data", returnData);
        intent.putExtra("outputFormat", Bitmap.CompressFormat.PNG.toString());
        return intent;
    }

    public static Intent buildImageCropIntent(Uri uriFrom, Uri uriTo, int outputX, int outputY, boolean returnData) {
        return buildImageCropIntent(uriFrom, uriTo, 1, 1, outputX, outputY, returnData);
    }

    public static Intent buildImageCropIntent(Uri uriFrom, Uri uriTo, int aspectX, int aspectY,
                                              int outputX, int outputY, boolean returnData) {
        Intent intent = new Intent("com.android.camera.action.CROP");
        intent.setDataAndType(uriFrom, "image/*");
        intent.putExtra("crop", "true");
        intent.putExtra("output", uriTo);
        intent.putExtra("aspectX", aspectX);
        intent.putExtra("aspectY", aspectY);
        intent.putExtra("outputX", outputX);
        intent.putExtra("outputY", outputY);
        intent.putExtra("scale", true);
        intent.putExtra("return-data", returnData);
        intent.putExtra("outputFormat", Bitmap.CompressFormat.PNG.toString());
        return intent;
    }

    public static Intent buildImageCaptureIntent(Uri uri) {
        Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
        intent.putExtra(MediaStore.EXTRA_OUTPUT, uri);
        return intent;
    }

    public static int calculateInSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight) {
        int h = options.outHeight;
        int w = options.outWidth;
        int inSampleSize = 0;
        if (h > reqHeight || w > reqWidth) {
            float ratioW = (float) w / reqWidth;
            float ratioH = (float) h / reqHeight;
            inSampleSize = (int) Math.min(ratioH, ratioW);
        }
        inSampleSize = Math.max(1, inSampleSize);
        return inSampleSize;
    }

    public static Bitmap getSmallBitmap(String filePath, int reqWidth, int reqHeight) {
        BitmapFactory.Options options = new BitmapFactory.Options();
        options.inJustDecodeBounds = true;
        BitmapFactory.decodeFile(filePath, options);
        options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
        options.inJustDecodeBounds = false;
        return BitmapFactory.decodeFile(filePath, options);
    }

    public byte[] compressBitmapToBytes(String filePath, int reqWidth, int reqHeight, int quality) {
        Bitmap bitmap = getSmallBitmap(filePath, reqWidth, reqHeight);
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        bitmap.compress(Bitmap.CompressFormat.JPEG, quality, baos);
        byte[] bytes = baos.toByteArray();
        bitmap.recycle();
        Log.i(TAG, "Bitmap compressed success, size: " + bytes.length);
        return bytes;
    }

    public byte[] compressBitmapSmallTo(String filePath, int reqWidth, int reqHeight, int maxLenth) {
        int quality = 100;
        byte[] bytes = compressBitmapToBytes(filePath, reqWidth, reqHeight, quality);
        while (bytes.length > maxLenth && quality > 0) {
            quality = quality / 2;
            bytes = compressBitmapToBytes(filePath, reqWidth, reqHeight, quality);
        }
        return bytes;
    }

    public byte[] compressBitmapQuikly(String filePath) {
        return compressBitmapToBytes(filePath, 480, 800, 50);
    }

    public byte[] compressBitmapQuiklySmallTo(String filePath, int maxLenth) {
        return compressBitmapSmallTo(filePath, 480, 800, maxLenth);
    }

    final static int ROUNDED_CORNER_COLOR = 0xff424242;
    /**
     * Get Rounded Corner Bitmap
     * @param bitmap ori bitmap
     * @param roundPx round size
     * @return new bitmap
     */
    public static Bitmap getRoundedCornerBitmap(Bitmap bitmap,float roundPx){

        Bitmap output = Bitmap.createBitmap(bitmap.getWidth(), bitmap
                .getHeight(), Bitmap.Config.ARGB_8888);
        Canvas canvas = new Canvas(output);

        final Paint paint = new Paint();
        final Rect rect = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight());
        final RectF rectF = new RectF(rect);

        paint.setAntiAlias(true);
        canvas.drawARGB(0, 0, 0, 0);
        paint.setColor(ROUNDED_CORNER_COLOR);
        canvas.drawRoundRect(rectF, roundPx, roundPx, paint);

        paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
        canvas.drawBitmap(bitmap, rect, rect, paint);

        return output;
    }

    public static Bitmap createCircleImage(Bitmap source)
    {
        int height = source.getHeight();
        int min = source.getHeight();
        final Paint paint = new Paint();
        paint.setAntiAlias(true);
        Bitmap target = Bitmap.createBitmap(min, min, Bitmap.Config.ARGB_8888);
        /**
         * 产生一个同样大小的画布
         */
        Canvas canvas = new Canvas(target);
        /**
         * 首先绘制圆形
         */
        canvas.drawCircle(min / 2, height / 2, min / 2, paint);
        /**
         * 使用SRC_IN
         */
        paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
        /**
         * 绘制图片
         */
        canvas.drawBitmap(source, 0, 0, paint);
        return target;
    }

    public static Bitmap getBitmapFromResId(Context context,int resId){
        Bitmap  bitmap = BitmapFactory.decodeResource(context.getResources(), resId);
        return bitmap;
    }

    /**
     * 是否是图片
     * @param ext
     * @return
     */
    public static boolean isImage(String ext){
        ArrayList<String> list = new ArrayList<String>();
        list.add("jpg");
        list.add("jpeg");
        list.add("png");
        list.add("bmp");
        if(list.contains(ext.toLowerCase())){
            return true;
        }
        else{
            return false;
        }
    }
    public static Bitmap getBitmap(String imgPath) {
        BitmapFactory.Options newOpts = new BitmapFactory.Options();
        newOpts.inJustDecodeBounds = false;
        newOpts.inSampleSize = 1;
        newOpts.inPreferredConfig = Bitmap.Config.RGB_565;
        return BitmapFactory.decodeFile(imgPath, newOpts);
    }
    public static String smallBitmap(Context mContext, String srcfilepath, int newWidth, int newHeight, long filesize, String fname) throws IOException {


        String path = SdCardUtil.getCurrAppSaveDir(mContext,"temp",true)+"//"+fname + ".jpg";//dir.getSaveDir(fname + ".jpg");
        Bitmap OldBitmap = getBitmap(srcfilepath);
        int oldWidth = OldBitmap.getWidth();
        int oldHeight = OldBitmap.getHeight();
        float scaleWidth = ((float) newWidth) / oldWidth;
        float scaleHeight = ((float) newHeight) / oldHeight;
        float scale;
        int startW,width;
        int startH,height;
        if(scaleWidth > scaleHeight){
            scale = scaleWidth;
            width = oldWidth;
            height = (int)((float)newHeight/scale);
            startW = 0;
            startH = (oldHeight-height)/2;
        }else{
            scale = scaleHeight;
            width = (int)((float)newWidth/scale);
            height = oldHeight;
            startW = (oldWidth-width)/2;
            startH = 0;
        }

        Matrix matrix = new Matrix();
        matrix.postScale(scale, scale);
        Bitmap bitmap1 = Bitmap.createBitmap(OldBitmap, startW, startH, width, height, matrix, true);
//        OldBitmap.recycle();
        ByteArrayOutputStream os = new ByteArrayOutputStream();
        // scale
        int options = 100;
        bitmap1.compress(Bitmap.CompressFormat.JPEG, options, os);
        long flenght = os.toByteArray().length;
        filesize = 300*1024;
        while ( flenght > filesize && options > 10) {
            os.reset();
            options -= 10;
            bitmap1.compress(Bitmap.CompressFormat.JPEG, options, os);
            flenght = os.toByteArray().length;
        }
        FileOutputStream fos = new FileOutputStream(path);
        fos.write(os.toByteArray());
        fos.flush();
        fos.close();
        return path;
    }

    public static String smallBitmap(Context mContext, String srcfilepath, long filesize, String fname) throws IOException {

        String path = SdCardUtil.getCurrAppSaveDir(mContext,"temp",true)+"//"+fname + ".jpg";//dir.getSaveDir(fname + ".jpg");
        Bitmap OldBitmap = getBitmap(srcfilepath);
        int oldWidth = OldBitmap.getWidth();
        int oldHeight = OldBitmap.getHeight();

        Matrix matrix = new Matrix();
        matrix.postScale(1, 1);
        Bitmap bitmap1 = Bitmap.createBitmap(OldBitmap, 0, 0, oldWidth, oldHeight, matrix, true);
//        OldBitmap.recycle();
        ByteArrayOutputStream os = new ByteArrayOutputStream();
        // scale
        int options = 100;
        bitmap1.compress(Bitmap.CompressFormat.JPEG, options, os);
        long flenght = os.toByteArray().length;
        filesize = 1024*1024;
        while ( flenght > filesize && options > 10) {
            os.reset();
            options -= 10;
            bitmap1.compress(Bitmap.CompressFormat.JPEG, options, os);
            flenght = os.toByteArray().length;
        }
        FileOutputStream fos = new FileOutputStream(path);
        fos.write(os.toByteArray());
        fos.flush();
        fos.close();
        return path;
    }

    public static String imgToBase64(String imgPath, int w, int h) {
        if (imgPath !=null && imgPath.length() > 0) {
            Bitmap bitmapo = getBitmap(imgPath);
            int width = bitmapo.getWidth();
            int height = bitmapo.getHeight();

            float scaleWidth = ((float) w) / width;
            float scaleHeight = ((float) h) / height;
            float scale = scaleHeight < scaleWidth ? scaleHeight:scaleWidth;
            Matrix matrix = new Matrix();
            matrix.postScale(scale, scale);
            Bitmap bitmap = Bitmap.createBitmap(bitmapo, 0, 0, width, height, matrix, true);


            ByteArrayOutputStream out = null;

            try {
                bitmapo.recycle();
                out = new ByteArrayOutputStream();
                bitmap.compress(Bitmap.CompressFormat.JPEG, 10 , out);
                byte[] btyes = out.toByteArray();
                byte[] imgBytes = Base64.encode(btyes,Base64.NO_WRAP);
                String base64 = new String(imgBytes);
//                return URLEncoder.encode( base64, "UTF-8");
                return base64;

            } catch (Exception e) {
                // TODO Auto-generated catch block
                return null;
            } finally {
                try {
                    out.flush();
                    out.close();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }else {
            return null;
        }
    }

    //不好使
//    public static Bitmap toRoundCorner(Bitmap bitmap) {
//        int height = bitmap.getHeight();
//        int width = bitmap.getHeight();
//        Bitmap output = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
//
//        Canvas canvas = new Canvas(output);
//
//        final Paint paint = new Paint();
//        final Rect rect = new Rect(0, 0, width, height);
//
//        paint.setAntiAlias(true);
//        canvas.drawARGB(0, 0, 0, 0);
//        //paint.setColor(0xff424242);
//        paint.setColor(Color.TRANSPARENT);
//        canvas.drawCircle(width / 2, height / 2, width / 2, paint);
//        paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
//        canvas.drawBitmap(bitmap, rect, rect, paint);
//        return output;
//    }
}
